package net.wantongtech.xa.uploadbasicinfo.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wtkj.vo.dzzf.base.xxjh.MessageSend;
import com.wtkj.zwxt.exceptions.BusinessException;
import lombok.extern.slf4j.Slf4j;
import net.wantongtech.xa.uploadbasicinfo.dao.CommonBaseDao;
import net.wantongtech.xa.uploadbasicinfo.dao.DealWithOldBatchPayDataDao;
import net.wantongtech.xa.uploadbasicinfo.vo.msg.HoldWithTransVo;
import net.wantongtech.xa.uploadbasicinfo.vo.msg.TransactionVo;
import net.wantongtech.xa.uploadbasicinfo.vo.msg.old.TransactionMessage;
import net.wantongtech.xa.uploadbasicinfo.vo.msg.old.WithholdMessage;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 处理旧的批量扣款数据
 *
 * @author MaShibo
 * 日期 :  2020/1/14
 */
@Slf4j
@Service
public class DealWithOldBatchPayDataService {


    /**
     * 存储
     */
    private static final String STORE_PATH = "C:\\temp\\batchPay";

    /**
     * 每个文件包含数量
     */
    private static final int PER_NUM = 500;

    @Resource
    private DealWithOldBatchPayDataDao dealWithOldBatchPayDataDao;

    @Resource
    private CommonBaseDao commonBaseDao;

    private ObjectMapper objectMapper = new ObjectMapper();


    @PostConstruct
    public void init() {
        File storePath = new File(STORE_PATH);
        if (!storePath.exists() && !storePath.mkdirs()) {
            throw new BusinessException(String.format("文件路径%s创建失败", storePath));
        }
    }

    public void dealWith() {
        List<MessageSend> messageSendList = dealWithOldBatchPayDataDao.queryOldBatchPayData();
        log.info("共有{}条待处理的数据", messageSendList.size());
        if (messageSendList.isEmpty()) {
            return;
        }

        messageSendList.forEach(messageSend -> {
            try {
                processSingle(messageSend);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        });

    }

    private void processSingle(MessageSend messageSend) throws IOException {
        long msgId = messageSend.getMsgId();
        String channelType = messageSend.getChannelType();
        log.info("开始处理channelType为：{}，msgId为：{}的批量扣款数据", channelType, msgId);
        String msgBody = messageSend.getMsgBody();
        WithholdMessage withholdMessage = objectMapper.readValue(msgBody, WithholdMessage.class);
        List<TransactionMessage> transactionMsgList = withholdMessage.getTransaction();
        log.info("共对应{}条原始交易信息", transactionMsgList.size());
        Map<String, TransactionMessage> transactionMessageMap = transactionMsgList
                .stream().collect(Collectors.toMap(TransactionMessage::getTransactionId, v -> v));

        List<String> transactionIdList = transactionMsgList.stream()
                .map(TransactionMessage::getTransactionId).collect(Collectors.toList());
        List<TransactionVo> integratedTransList = commonBaseDao.queryIntegratedTransById(transactionIdList, channelType);
        int total = integratedTransList.size();
        log.info("共查询出{}条原始交易信息", total);
        if (transactionIdList.size() != total) {
            log.error("查询数量与原数量不一致");
            return;
        }


        integratedTransList.forEach(transactionVo -> {
            String integratedId = transactionVo.getIntegratedId();
            TransactionMessage transactionMessage = transactionMessageMap.get(integratedId);

            String enTollStationName = transactionVo.getEnTollStationName();
            if (StringUtils.isBlank(enTollStationName)) {
                transactionVo.setEnTollStationName(transactionMessage.getEnTollStationName());
            }

            String exTollStationName = transactionVo.getExTollStationName();
            if (StringUtils.isBlank(exTollStationName)) {
                transactionVo.setExTollStationName(transactionMessage.getExTollStationName());
            }

        });

        if (total > PER_NUM) {
            List<TransactionVo> subTransVoList = integratedTransList.subList(0, PER_NUM);
            log.info("截取{}条数据", subTransVoList.size());
            buildHoldWithTrans(msgId, channelType, subTransVoList);

            Long newMsgId = obtainMessageId(channelType);
            log.info("获取新msgId：{}", newMsgId);
            List<TransactionVo> subTransVoList2 = integratedTransList.subList(PER_NUM, integratedTransList.size());
            log.info("截取{}条数据", subTransVoList2.size());
            buildHoldWithTrans(newMsgId, channelType,
                    subTransVoList2);
        } else {
            buildHoldWithTrans(msgId, channelType, integratedTransList);
        }
    }

    private void buildHoldWithTrans(long msgId, String channelType,
                                    List<TransactionVo> integratedTransList) throws IOException {
        HoldWithTransVo transVo = new HoldWithTransVo();
        transVo.setMessageId(msgId);
        transVo.setCount(integratedTransList.size());
        long amount = integratedTransList.stream().mapToLong(TransactionVo::getFee).sum();
        transVo.setAmount(amount);
        transVo.setPublishType(0);
        transVo.setTransaction(integratedTransList);
        objectMapper.writeValue(new File(STORE_PATH, String.format("%s-%s.json", channelType, msgId)), transVo);
    }


    private Long obtainMessageId(String channelType) {
        return commonBaseDao.querySeqNetVal(String.format("SEQUENCE%s", channelType));
    }


    public static void main(String[] args) {
        File dir = new File("C:\\Users\\MaShibo\\Desktop\\batchPay-v3");
        File[] jsonFiles = dir.listFiles((dir1, name) -> name.startsWith("BOC") && name.endsWith(".json"));
        if (jsonFiles == null || jsonFiles.length < 1) {
            return;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        List<HoldWithTransVo> holdWithTransVoList = Arrays.stream(jsonFiles).map(v -> {
            try {
                return objectMapper.readValue(v, HoldWithTransVo.class);
            } catch (IOException e) {
                throw new BusinessException("解析失败");
            }
        }).collect(Collectors.toList());
        long amount = holdWithTransVoList.stream().mapToLong(HoldWithTransVo::getAmount).sum();
        int count = holdWithTransVoList.stream().mapToInt(HoldWithTransVo::getCount).sum();
        log.info("共{}个包，{}笔交易，总金额：{}分", holdWithTransVoList.size(), count, amount);

    }

}
